home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / plane / _delaunay_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  41.5 KB  |  1,558 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _delaunay_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. /*****************************************************************************
  16. +
  17. +    Delaunay tree    by Olivier Devillers
  18. +
  19. +        Fully dynamic construction of the Delaunay triangulation with
  20. +        good randomized complexity
  21. +
  22. +    Copyright (c) 1990
  23. +    INRIA, 2004 route des Lucioles, 06 565 Valbonne Cedex, France
  24. +
  25. +
  26. ******************************************************************************/
  27.  
  28.  
  29. #include <LEDA/impl/delaunay_tree.h>
  30.  
  31.  
  32. #define Fini        0
  33. #define Infini1     1        /* 1 point a l'infini */
  34. #define Infini2        2        /* 2 points a l'infini */
  35. #define Infini3        3        /* 3 points a l'infini, c'est la racine */
  36. #define Impossible    99        /* Le voisin du precedent */
  37. #define U 0                /* indices pour les trois sommets */
  38. #define V 1
  39. #define W 2
  40.  
  41.  
  42. /*****************************************************************************
  43.  
  44.             Declarations de type
  45.  
  46. ******************************************************************************/
  47.  
  48.  
  49. struct LISTENOEUD{
  50.     NOEUD *item;
  51.     LISTENOEUD *next;
  52. };
  53.  
  54.  
  55.  
  56. struct REINSERER {
  57.     DT_item    x;                /* a point devant etre reinserer */
  58.     NOEUD   *detruit1,            /* triangles a detruire si ils existent */
  59.         *detruit2;            /* NULL sinon xpx1 est direct et xpx2 indirect*/
  60.     listenoeud
  61.         decroches;            /* triangles decroches */
  62.     REINSERER
  63.         *finf,*fsup;        /* pour l'arbre binaire */
  64. };
  65.  
  66.  
  67.  
  68. struct STAR{
  69.     STAR
  70.             *next,*previous;/*arete suivante et precedente sur le polygone*/
  71.     NOEUD
  72.             *triangle;        /* triangle adjacent */
  73.     int        n,p,arete;        /*point suivant, precedent, arete dans le triangle*/
  74. };
  75.  
  76.  
  77.  
  78.  
  79. struct NOEUD{
  80.  
  81.     int        type;    /* le triangle est Fini ou Infini[123] 
  82.                    dans le cas d'un triangle infini, les sommets
  83.                    infinis sont la direction a` l'infini */
  84.     
  85.     int        degenere;  /* booleen, 3 pts alignes ? */
  86.     int        direct;       /* booleen, le triangle est-il direct ? */
  87.         int             stacked;
  88.     int        visite;       /* triangle marque visite si ce flag
  89.                           est le flag courant.
  90.                       pour la suppression le triangle est
  91.                                   marque si il appartient ou a
  92.                                   appartenu a A 
  93.                                 */
  94.     
  95.     int        detruire;   /* le triangle est a detruire si ce flag
  96.                        est le flag courant */
  97.     coord     cx,cy;            /* centre du cercle 
  98.                                           (uniqu^t pour tracer voronoi)*/
  99.     coord    a2,b2,a3,b3,c1,z0,z1,z2; /* pour les tests de conflit */
  100.     
  101.     DT_item    meurtrier; /* NULL si le triangle n'est pas mort */
  102.     DT_item    s[3];       /* sommets du triangle */
  103.                    /* U est le createur */
  104.                    /* si Infini1 alors W est a l'infini */
  105.                    /* si Infini2 alors V et W sont a l'infini */
  106.                    /* si Infini3 alors U,V et W sont a l'infini*/
  107.     NOEUD
  108.             *pere,        /* pere */
  109.             *bpere,        /* beau-pere */
  110.             *fils[3];    /* fils */
  111.     listenoeud
  112.             bfils;        /* liste des beaux-fils */
  113.     NOEUD
  114.             *voisin[3],    /* 3 voisins (courant ou a la mort) */
  115.             *creation[3],    /* 3 voisins a la creation */
  116.             *special[3];    /* 3 voisins speciaux! */
  117.     star    Star[3];        /* pointeur reciproque vers Star */
  118.  
  119.  
  120. };
  121.  
  122. /*****************************************************************************
  123.  
  124.             Allocation memoire
  125.  
  126. ******************************************************************************/
  127.  
  128. #define SIZEALLOC 100
  129.  
  130.  
  131. char* delaunay_tree::alloc_block(int size)
  132. {
  133.    char* p =  (char*)malloc( size + sizeof(double) ); 
  134.  
  135.    if (!p) error_handler(1,"out of memory");
  136.  
  137.    *((char**)p) = used_blocks;
  138.    used_blocks = p;
  139.  
  140.    return (used_blocks+sizeof(double)) ; 
  141.  }
  142.  
  143.  
  144. void delaunay_tree::free_blocks()
  145. {
  146.   char* p;
  147.   while (used_blocks)
  148.   { p = used_blocks;
  149.     used_blocks = *((char**)used_blocks);
  150.     free(p);
  151.    }
  152. }
  153.  
  154. void delaunay_tree::poubelle_point(DT_item p)
  155. { p->cree = (noeud) Poubelle_point;
  156.   Poubelle_point = p;
  157. }
  158.  
  159. DT_item delaunay_tree::vrai_alloc_point()
  160. {
  161.  if ( ! item_nombre ) {
  162.         item_next = (DT_item) alloc_block( (item_nombre = SIZEALLOC) * sizeof(DT_POINT) ) ; 
  163.     }
  164.     item_nombre--;
  165.     return item_next++;
  166. }
  167.  
  168. DT_item delaunay_tree::alloc_point()
  169. {
  170.     if ( Poubelle_point ) { DT_item p = Poubelle_point;
  171.                 Poubelle_point = (DT_item) Poubelle_point->cree;
  172.                 return p;  }
  173.     return vrai_alloc_point();
  174. }
  175.  
  176.  
  177. void delaunay_tree::poubelle_listenoeud(listenoeud p)
  178. {
  179.   p->next =  Poubelle_listenoeud;
  180.   Poubelle_listenoeud = p;
  181. }
  182.  
  183. listenoeud delaunay_tree::vrai_alloc_listenoeud()
  184. {
  185.  if ( ! listenoeud_nombre ) {
  186.         listenoeud_next = (listenoeud) alloc_block((listenoeud_nombre = SIZEALLOC) * sizeof(LISTENOEUD) ) ; 
  187.     }
  188.     listenoeud_nombre--;
  189.     return listenoeud_next++;
  190. }
  191.  
  192. listenoeud delaunay_tree::alloc_listenoeud()
  193. {
  194.     if ( Poubelle_listenoeud ) 
  195.                               { listenoeud p = Poubelle_listenoeud;
  196.                     Poubelle_listenoeud = Poubelle_listenoeud->next;
  197.                 return p;  }
  198.     return vrai_alloc_listenoeud();
  199. }
  200.  
  201.  
  202. void delaunay_tree::poubelle_noeud(noeud p)
  203. /* on ne se resert que des noeud dont le champs detruire n'est pas flag */
  204.   p->fils[0] =  Poubelle_noeud;
  205.   Poubelle_noeud = p;
  206.   if (fl != p->detruire ) { fl = p->detruire; Libre_noeud = Poubelle_noeud ;}
  207. }
  208.  
  209. noeud delaunay_tree::vrai_alloc_noeud()
  210. {
  211.  if ( ! noeud_nombre ) {
  212.         noeud_next = (noeud) alloc_block((noeud_nombre = SIZEALLOC) * sizeof(NOEUD) ) ; 
  213.     }
  214.     noeud_nombre--;
  215.     return noeud_next++;
  216. }
  217.  
  218. noeud delaunay_tree::alloc_noeud()
  219. /* on ne se resert que des noeud dont le champs detruire n'est pas flag */
  220. {    
  221.     if (Libre_noeud && Libre_noeud->fils[0] )
  222.             { noeud p = Libre_noeud->fils[0];
  223.               Libre_noeud->fils[0] = Libre_noeud->fils[0]->fils[0];
  224.               return p;  }
  225.     return vrai_alloc_noeud();
  226. }
  227.  
  228.  
  229. void delaunay_tree::poubelle_star(star p)
  230. {
  231.   p->next =  Poubelle_star;
  232.   Poubelle_star = p;
  233. }
  234.  
  235. star delaunay_tree::vrai_alloc_star()
  236. {
  237.  if ( ! star_nombre ) {
  238.         star_next = (star) alloc_block((unsigned int) (star_nombre = SIZEALLOC) * sizeof(STAR) ) ; 
  239.     }
  240.     star_nombre--;
  241.     return star_next++;
  242. }
  243.  
  244.  
  245. star delaunay_tree::alloc_star()
  246. {
  247.     if ( Poubelle_star ) { star p = Poubelle_star;
  248.                    Poubelle_star = Poubelle_star->next;
  249.                    return p;  }
  250.     return vrai_alloc_star();
  251. }
  252.  
  253.  
  254. void delaunay_tree::poubelle_reinserer( reinserer p)
  255. {
  256.   p->finf =  Poubelle_reinserer;
  257.   Poubelle_reinserer = p;
  258. }
  259.  
  260. reinserer delaunay_tree::vrai_alloc_reinserer()
  261. {
  262.  if ( ! reinserer_nombre ) {
  263.         reinserer_next = (reinserer) alloc_block((reinserer_nombre = SIZEALLOC) * sizeof(REINSERER) ) ; 
  264.     }
  265.     reinserer_nombre--;
  266.     return reinserer_next++;
  267. }
  268.  
  269.  
  270. reinserer delaunay_tree::alloc_reinserer()
  271. {
  272.     if ( Poubelle_reinserer ) {reinserer p = Poubelle_reinserer;
  273.                       Poubelle_reinserer = Poubelle_reinserer->finf;
  274.                    return p;  }
  275.  
  276.     return vrai_alloc_reinserer();
  277. }
  278.  
  279. /*****************************************************************************
  280.  
  281.             Structure Reinsert
  282.  
  283. ******************************************************************************/
  284.  
  285. reinserer delaunay_tree::locate( reinserer n, DT_item x)
  286. {
  287.     reinserer nn;
  288.  
  289.     if ( ! Reinsert ) {
  290.         nn = alloc_reinserer();
  291.         nn->x = x;
  292.         nn->decroches = NULL;
  293.         nn->detruit1 = NULL;
  294.         nn->detruit2 = NULL;
  295.         nn->finf = NULL;
  296.         nn->fsup = NULL;
  297.         Reinsert = nn;
  298.      return nn;
  299.     }
  300.     if ( n->x == x) return n;
  301.     if ( x->n < n->x->n ) {
  302.         if (n->finf) return locate(n->finf,x);
  303.         nn = alloc_reinserer();
  304.         nn->x = x;
  305.         nn->decroches = NULL;
  306.         nn->detruit1 = NULL;
  307.         nn->detruit2 = NULL;
  308.         nn->finf = NULL;
  309.         nn->fsup = NULL;
  310.         n->finf = nn;
  311.     } else {
  312.         if (n->fsup) return locate(n->fsup,x);
  313.         nn = alloc_reinserer();
  314.         nn->x = x;
  315.         nn->decroches = NULL;
  316.         nn->detruit1 = NULL;
  317.         nn->detruit2 = NULL;
  318.         nn->finf = NULL;
  319.         nn->fsup = NULL;
  320.         n->fsup = nn;
  321.     }
  322.     return nn;
  323. }
  324.  
  325. void delaunay_tree::clear_Reinsert( reinserer n)
  326. {    listenoeud l,ll;
  327.     if ( ! Reinsert ) return;
  328.     if (n->finf) clear_Reinsert(n->finf);
  329.     if (n->fsup) clear_Reinsert(n->fsup);
  330.     for ( l = n->decroches; l; l = ll ) {ll = l->next; poubelle_listenoeud(l);}
  331.     poubelle_reinserer(n);
  332.     if ( n == Reinsert ) Reinsert = NULL;
  333. }
  334.  
  335. /*****************************************************************************
  336.  
  337.             Structure Star
  338.  
  339. ******************************************************************************/
  340.  
  341. void delaunay_tree::clear_Star()
  342. {
  343.     star s;
  344.  
  345.     if ( ! Star ) return;
  346.     for ( s = Star->next ; s != Star ;)
  347.                 {s = s->next; poubelle_star(s->previous);}
  348.     poubelle_star(Star);
  349.     Star = NULL;
  350. }
  351.  
  352. void delaunay_tree::init_Star( noeud n, int i, int j, int k)
  353. /* l'arete i,j de n est sur le bord de star */
  354. {
  355.     star s;
  356.  
  357.     if (! n) {
  358.         Star->next = first_star;
  359.         first_star->previous = Star;
  360.         first_star = NULL;
  361.         return;
  362.     }
  363.     s = alloc_star();
  364.     s->triangle = n;
  365.     s->p = i;
  366.     s->n = j;
  367.     s->arete = k;
  368.     n->Star[k] = s ;
  369.     s->previous = Star;
  370.     if (! Star ) first_star = s;
  371.     else         Star->next = s;
  372.     Star = s;
  373. }
  374.  
  375. star delaunay_tree::loc_Star( DT_item xx)
  376. /* trouve l'arete telle que xx soit le point precedent */
  377. {
  378.     star s;
  379.  
  380.     s = Star;
  381.     while ( s->triangle->s[s->p] != xx ) s = s->next ;
  382.     return s;
  383. }
  384.  
  385. void delaunay_tree::split_Star( star n1,star n2)
  386. /* raccroche les n1 a n2 en viarant la partie intermediare */
  387. {
  388.     star s,ss;
  389.  
  390.     if (n1==n2) {
  391.         s = alloc_star();
  392.         s->previous = n1;
  393.         s->next = n1->next;
  394.         n1->next = s;
  395.         s->next->previous = s;
  396.         return;
  397.     }
  398.     for ( s = n1->next; s != n2 ; ){ss=s->next; poubelle_star(s); s=ss; }
  399.     n1->next = n2;
  400.     Star = n2->previous = n1;
  401. }
  402.  
  403. /*****************************************************************************
  404.  
  405.             Procedures
  406.  
  407. ******************************************************************************/
  408.  
  409. void delaunay_tree::beaufils( noeud bf, noeud bp)
  410. /* ajoute bf a la liste des beaufils de bp */
  411. {
  412.     listenoeud nov;
  413.  
  414.     nov = alloc_listenoeud();
  415.     nov->next = bp->bfils;
  416.     nov->item = bf;
  417.     bp->bfils = nov;
  418. }
  419.  
  420. void delaunay_tree::plusbeaufils( noeud bf, noeud bp)
  421. /* enleve bf a la liste des beaufils de bp */
  422. {
  423.     listenoeud n,nn;
  424.  
  425.     if ( bp->bfils->item == bf ) {
  426.         nn = bp->bfils;
  427.         bp->bfils = bp->bfils->next ;
  428.         poubelle_listenoeud(nn);
  429.         return;
  430.     }
  431.     for ( n = bp->bfils; n->next->item != bf; n = n->next );
  432.     nn = n->next ;
  433.     n->next = n->next->next ;
  434.     poubelle_listenoeud(nn);
  435. }
  436.  
  437. void delaunay_tree::demiplan( noeud t)
  438. /* calcul de la normale */
  439. {
  440.     t->type = Infini1;
  441.     t->degenere = 0;
  442.     if ( t->direct ) {
  443.             t->cx= t->s[U]->y - t->s[V]->y ;
  444.             t->cy= t->s[V]->x - t->s[U]->x ;
  445.     } else {
  446.             t->cx= t->s[V]->y - t->s[U]->y ;
  447.             t->cy= t->s[U]->x - t->s[V]->x ;
  448.     }
  449. }
  450.  
  451. void delaunay_tree::cercle( noeud t)
  452. {
  453.     register double a,b,c,d;
  454. /* calcul pour les tests de conflits */
  455.        t->a2 = t->s[1]->x - t->s[0]->x ;
  456.        t->b2 = t->s[1]->y - t->s[0]->y ;
  457.        t->a3 = t->s[2]->x - t->s[0]->x ;
  458.        t->b3 = t->s[2]->y - t->s[0]->y ;
  459.  
  460.        t->c1 = t->a2 * t->b3 - t->a3 * t->b2 ;
  461.        t->z1 = t->a2 * (t->s[1]->x + t->s[0]->x) + t->b2 * (t->s[1]->y+t->s[0]->y);
  462.        t->z2 = t->a3 * (t->s[2]->x + t->s[0]->x) + t->b3 * (t->s[2]->y+t->s[0]->y);
  463. /* calcul du centre et du rayon du cercle  */
  464.     a = t->s[U]->x * t->s[U]->x + t->s[U]->y * t->s[U]->y ;
  465.     b = t->s[V]->x * t->s[V]->x + t->s[V]->y * t->s[V]->y - a ;
  466.     c = t->s[W]->x * t->s[W]->x + t->s[W]->y * t->s[W]->y - a ;
  467.     d = 2*( (t->s[V]->x - t->s[U]->x) * (t->s[W]->y - t->s[U]->y)
  468.                 - (t->s[W]->x - t->s[U]->x) * (t->s[V]->y - t->s[U]->y));
  469.     if ( (t->degenere = (d==0) ) ) { 
  470.                         t->cx= t->pere->cx ;
  471.                         t->cy= t->pere->cy ;
  472.                     return;
  473.                 }
  474.     t->cx=(b*(t->s[W]->y - t->s[U]->y)-c*(t->s[V]->y - t->s[U]->y))/d;
  475.     t->cy=(c*(t->s[V]->x - t->s[U]->x)-b*(t->s[W]->x - t->s[U]->x))/d;
  476. }
  477.  
  478. int delaunay_tree::confondu( DT_item a, DT_item b)
  479. {
  480.     return ((a->x == b->x)&&(a->y==b->y));
  481. }
  482.  
  483. int delaunay_tree::direct( noeud n)
  484. /* teste si un triangle est direct */
  485. {
  486.     switch(n->type){
  487.     case Fini       : 
  488.         return ((n->s[V]->x - n->s[U]->x)*(n->s[W]->y - n->s[U]->y)
  489.                 - (n->s[V]->y - n->s[U]->y)*(n->s[W]->x - n->s[U]->x) > 0);
  490.     case Infini1     :
  491.         return ((n->s[V]->x - n->s[U]->x)*n->s[W]->y
  492.                 - (n->s[V]->y - n->s[U]->y)*n->s[W]->x > 0);
  493.     case Infini2     :
  494.         return (n->s[V]->x*n->s[W]->y - n->s[V]->y*n->s[W]->x > 0);
  495.     case Infini3     : return 1;
  496.     case Impossible  : return 1;
  497.     }
  498.     return 2;
  499. }
  500.  
  501.  
  502. int delaunay_tree::conflit(noeud n, DT_item p)
  503. {
  504.   /* teste si un point est en conflit avec une region */
  505.  
  506.     register coord a1,c2,c3,z0;
  507.  
  508.     switch(n->type){
  509.     case Fini       :
  510.         a1 = p->x - n->s[0]->x ;
  511.         c3 = p->y - n->s[0]->y ;
  512.  
  513.         z0 = a1 * (p->x + n->s[0]->x) + c3 * (p->y + n->s[0]->y) ;
  514.  
  515.         c2 = n->a3 * c3 - a1 * n->b3 ;
  516.         c3 = a1 * n->b2 - n->a2 * c3 ;
  517.  
  518.             /********** Arithmetique double precision ************/
  519.             /*      On utilise le fait que les flottants de l'accelerateur
  520.                     flottant sont stockes avec une mantisse de 64 bits !!!
  521.                     Pour faire du calcul entier juste, faite le en flottant !
  522.             */
  523.  
  524.         a1=(double)z0*(double)n->c1 + (double)n->z1*(double)c2 +
  525.                                     (double)n->z2*(double)c3;
  526.         return (n->direct ? ( a1 <= 0.0)  : (a1 >= 0.0) );
  527.     case Infini1    :
  528.         if ( ( (p->x - n->s[U]->x)* (n->s[U]->y - n->s[V]->y)
  529.                 + (p->y - n->s[U]->y)* (n->s[V]->x - n->s[U]->x) ) == 0 )
  530.         {               z0 = n->s[U]->x - p->x;
  531.                         a1 = n->s[U]->y - p->y;
  532.                         c2 = n->s[V]->x - p->x;
  533.                         c3 = n->s[V]->y - p->y;
  534.                         return ( z0*c2 + a1*c3 < 0);
  535.         }else return (n->direct)
  536.             ?   ( ( (p->x - n->s[U]->x)* (n->s[U]->y - n->s[V]->y)
  537.                     + (p->y - n->s[U]->y)* (n->s[V]->x - n->s[U]->x) ) > 0 )
  538.             :   ( ( (p->x - n->s[U]->x)* (n->s[V]->y - n->s[U]->y)
  539.                     + (p->y - n->s[U]->y)* (n->s[U]->x - n->s[V]->x) ) > 0 ) ;
  540.     case Infini2    :
  541.                 return ( (p->x - n->s[U]->x) * (n->s[V]->x + n->s[W]->x)
  542.                     +(p->y - n->s[U]->y) * (n->s[V]->y + n->s[W]->y) > 0 );
  543.     case Infini3    : return 1;
  544.     case Impossible : return 0;
  545.     }
  546.     return 0;
  547. }
  548.  
  549. //int delaunay_tree::conflit( noeud n, DT_item p)
  550. ///* teste si un point est en conflit avec une region */
  551. //{
  552. //    register coord a1,c2,c3,z0;
  553. //
  554. //    switch(n->type){
  555. //    case Fini        :
  556. //        a1 = p->x - n->s[0]->x ;
  557. //        c3 = p->y - n->s[0]->y ;
  558. //
  559. //        z0 = a1 * (p->x + n->s[0]->x) + c3 * (p->y + n->s[0]->y) ;
  560. //     
  561. //        c2 = n->a3 * c3 - a1 * n->b3 ;
  562. //        c3 = a1 * n->b2 - n->a2 * c3 ;
  563. // 
  564. //    /********** Arithmetique double precision ************/
  565. //    /* On utilise le fait que les flottants de l'accelerateur
  566. //       flottant sont stockes avec une mantisse de 64 bits !!!
  567. //           Pour faire du calcul entier juste, faite le en flottant !
  568. //    */
  569. // 
  570. //    a1=(double)z0*(double)n->c1 + (double)n->z1*(double)c2 + (double)n->z2*(double)c3;
  571. //        return (n->direct ? ( a1 <= 0.0)  : (a1 >= 0.0) );
  572. //
  573. //    case Infini1    : 
  574. //        return (n->direct)
  575. //            ?    ( ( (p->x - n->s[U]->x)* (n->s[U]->y - n->s[V]->y)
  576. //                    + (p->y - n->s[U]->y)* (n->s[V]->x - n->s[U]->x) ) >= 0 )
  577. //            :    ( ( (p->x - n->s[U]->x)* (n->s[V]->y - n->s[U]->y)
  578. //                    + (p->y - n->s[U]->y)* (n->s[U]->x - n->s[V]->x) ) >= 0 ) ;
  579. //    case Infini2    :
  580. //                return ( (p->x - n->s[U]->x) * (n->s[V]->x + n->s[W]->x)
  581. //                    +(p->y - n->s[U]->y) * (n->s[V]->y + n->s[W]->y) >= 0 );
  582. //    case Infini3    : return 1;
  583. //    case Impossible : return 0;
  584. //    }
  585. //    return 0;
  586. //}
  587.  
  588.  
  589.  
  590. void delaunay_tree::clear()
  591. {
  592.   if (arbre != nouveau)
  593.   { flag++;
  594.     arbre->s[U]->visite = flag;
  595.     arbre->s[V]->visite = flag;
  596.     arbre->s[W]->visite = flag;
  597.     clear_items(nouveau);
  598.    }
  599.   free_blocks();
  600.   init();
  601. }
  602.  
  603. delaunay_tree::~delaunay_tree() { clear(); }
  604.  
  605. delaunay_tree::delaunay_tree()  { init(); }
  606.  
  607. void delaunay_tree::init()
  608. /* initialisation du Delaunay tree avec les trois points a l'infini */
  609. {
  610.         counter = 0;
  611.         flag=1; 
  612.         Star = NULL; 
  613.         Reinsert = NULL; 
  614.         Poubelle_noeud = Libre_noeud = NULL;
  615.  
  616.         used_blocks=NULL;
  617.         Poubelle_point=NULL;
  618.         Poubelle_listenoeud=NULL;
  619.         Poubelle_noeud=NULL;
  620.         Libre_noeud=NULL;
  621.         Poubelle_star=NULL;
  622.         Poubelle_reinserer=NULL;
  623.         fl = 0;
  624.         item_nombre = 0;
  625.         item_next = 0;
  626.         listenoeud_nombre = 0;
  627.         listenoeud_next = 0;
  628.         noeud_nombre = 0;
  629.         noeud_next = 0;
  630.         star_nombre = 0;
  631.         star_next = 0;
  632.         reinserer_nombre = 0;
  633.         reinserer_next = 0;
  634.         first_star=NULL;
  635.  
  636.  
  637.     arbre = alloc_noeud();
  638.     nouveau = arbre;
  639.  
  640.     arbre->type = Infini3;
  641.     arbre->degenere = 0;
  642.     arbre->visite = 0;
  643.     arbre->stacked = 0;
  644.     arbre->detruire = 0;
  645.     arbre->meurtrier = NULL;
  646.     arbre->fils[U] = arbre->fils[V] = arbre->fils[W] = NULL ;
  647.     arbre->bfils = NULL;
  648.     arbre->pere = NULL;
  649.     arbre->bpere = NULL;
  650.     arbre->voisin[U] =
  651.     arbre->voisin[V] =
  652.     arbre->voisin[W] =
  653.     arbre->creation[U] =
  654.     arbre->creation[V] =
  655.     arbre->creation[W] = alloc_noeud();
  656.     arbre->direct = 1;
  657.  
  658.     arbre->voisin[W]->visite = 0;
  659.     arbre->voisin[W]->stacked = 0;
  660.     arbre->voisin[W]->type = Impossible ;
  661.     arbre->voisin[W]->degenere = 0;
  662.     arbre->voisin[W]->meurtrier = NULL ;
  663.     arbre->voisin[W]->fils[U] = arbre->voisin[W]->fils[V] =
  664.                             arbre->voisin[W]->fils[W] = NULL ;
  665.     arbre->voisin[W]->bfils = NULL ;
  666.     arbre->voisin[W]->pere = NULL ;
  667.     arbre->voisin[W]->bpere = NULL ;
  668.     arbre->voisin[W]->voisin[U] =
  669.     arbre->voisin[W]->voisin[V] =
  670.     arbre->voisin[W]->voisin[W] =
  671.     arbre->voisin[W]->creation[U] =
  672.     arbre->voisin[W]->creation[V] =
  673.     arbre->voisin[W]->creation[W] = arbre ;
  674.     arbre->voisin[W]->direct = 0;
  675.  
  676.     arbre->s[U] = arbre->voisin[W]->s[U] = alloc_point();
  677.     arbre->s[V] = arbre->voisin[W]->s[V] = alloc_point();
  678.     arbre->s[W] = arbre->voisin[W]->s[W] = alloc_point();
  679.     arbre->s[U]->x =  2;
  680.     arbre->s[U]->y =  0;
  681.     arbre->s[V]->x = -1;
  682.     arbre->s[V]->y =  2;
  683.     arbre->s[W]->x = -1;
  684.     arbre->s[W]->y = -2;
  685.     arbre->s[U]->n = 0;
  686.     arbre->s[V]->n = 0;
  687.     arbre->s[W]->n = 0;
  688.  
  689. }
  690.  
  691. noeud delaunay_tree::Insert( noeud n, DT_item p)
  692. /* recherche d'un conflit */
  693. {
  694.     listenoeud l;
  695.     noeud nn;
  696.     int i;
  697.  
  698.     if ( flag != n->visite ) {
  699.      n->visite = flag;
  700.      if ( conflit(n,p)){
  701.         if ( n->meurtrier ) {
  702.             for (i=U; i<=W; i++) if ( n->fils[i] )
  703.                 if ( nn = Insert( n->fils[i], p) ) return nn ;
  704.         } else return n ;
  705.         for ( l = n->bfils; l ; l = l->next )
  706.                 if ( nn = Insert( l->item, p) ) return nn ;
  707.      }
  708.     }
  709.     return NULL ;
  710. }
  711.  
  712. noeud delaunay_tree::creenoeud( noeud pere, int i, DT_item p)
  713. {
  714.                 nouveau = pere->fils[i] = alloc_noeud();
  715.                 beaufils(nouveau, pere->voisin[i] );
  716.                 nouveau->visite = flag;
  717.                 nouveau->stacked = flag;
  718.                 nouveau->detruire = 0;
  719.                 nouveau->meurtrier = NULL;
  720.                 nouveau->fils[U] = nouveau->fils[V] = nouveau->fils[W] = NULL ;
  721.                 nouveau->bfils = NULL;
  722.                 nouveau->s[U]=p;                    /* createur */
  723.                 switch(i){
  724.                 case U: nouveau->direct = pere->direct;
  725.                         nouveau->s[V]= pere->s[V];
  726.                         nouveau->s[W]= pere->s[W]; break;
  727.                 case V: nouveau->direct = ! pere->direct;
  728.                         nouveau->s[V]= pere->s[U];
  729.                         nouveau->s[W]= pere->s[W]; break;
  730.                 case W: nouveau->direct = pere->direct;
  731.                         nouveau->s[V]= pere->s[U];
  732.                         nouveau->s[W]= pere->s[V]; break;
  733.                 }
  734.                 nouveau->pere = pere;
  735.                 nouveau->bpere =
  736.                 nouveau->voisin[U] =
  737.                 nouveau->creation[U] = pere->voisin[i];
  738.                                         /* nouveau est-il fini ou infini */
  739.                 switch ( pere->type ) {
  740.                 case Fini       :
  741.                     cercle(nouveau);
  742.                     nouveau->type = Fini; break;
  743.                 case Infini1    :
  744.                     switch (i) {
  745.                     case U: 
  746.                     case V: demiplan(nouveau); nouveau->type = Infini1;
  747.                             nouveau->degenere = 0; break;
  748.                     case W: cercle(nouveau); nouveau->type = Fini; break;
  749.                     }break;
  750.                 case Infini2    :
  751.                     switch (i) {
  752.                     case U: nouveau->type = Infini2;
  753.                             nouveau->degenere = 0;break; 
  754.                     case V:
  755.                     case W: nouveau->type = Infini1; demiplan(nouveau);
  756.                             nouveau->degenere = 0;break; 
  757.                     }break;
  758.                 case Infini3    : nouveau->type = Infini2;
  759.                                     nouveau->degenere = 0;break; 
  760.                 case Impossible : break;
  761.                 }
  762.     return nouveau;
  763. }
  764.  
  765. int delaunay_tree::creation( noeud detruit, DT_item p)
  766. /* creation eventuelle des nouveaux noeuds et des liens et des voisinages*/
  767. {
  768.     DT_item first= NULL;
  769.     noeud n1,father;
  770.     int arete;        /* indice sur n1 de l'arete axe-createur */ 
  771.     int a,b,c;        /* indice des trois sommets sur father */
  772.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  773.     int j;
  774.  
  775.     if ( ! detruit)
  776.                     return 0;
  777.         for (j=U; j<= W - detruit->type; j++) if (confondu(p,detruit->s[j]))
  778.                                     return 0;
  779.         detruit->meurtrier = p;
  780.         a = U; b = V; c = W;
  781.         while ( detruit->voisin[c]->meurtrier
  782.             || conflit ( detruit->voisin[c],p) )
  783.                 {
  784.            detruit->voisin[c]->meurtrier = p;
  785.            a1 = a; b1 = b; c1 = c;
  786.            for (j=U; j<=W; j++)
  787.            if (detruit->voisin[c1]->s[j] == detruit->s[a1]) 
  788.                        a=j;
  789.            else 
  790.                       if (detruit->voisin[c1]->s[j] == detruit->s[b1]) 
  791.                          c=j;
  792.                       else
  793.                          b=j;
  794.            detruit = detruit->voisin[c1] ;
  795.         }
  796.                 p->cree = n1 = creenoeud(detruit,c,p);
  797.                 /* n1 remplace pere comme voisin de son beau-pere*/
  798.                 for (j=U; j<=W; j++)
  799.                     if (    (detruit->voisin[c]->s[j] != n1->s[V])
  800.                         &&    (detruit->voisin[c]->s[j] != n1->s[W])) break;
  801.                 detruit->voisin[c]->voisin[j] = n1 ;
  802.                 switch (c) {
  803.                     case U : first = detruit->s[a=(detruit->direct) ? W : V ];
  804.                                     break;
  805.                     case V : first = detruit->s[a=(detruit->direct) ? U : W ];
  806.                                     break;
  807.                     case W : first = detruit->s[a=(detruit->direct) ? V : U ];
  808.                                     break;
  809.                 }
  810.                 b = c; c = U+V+W -b -a ;
  811.                 father = detruit;
  812.                 arete =  (n1->direct) ? V : W ;
  813.     do {
  814.                 /* ac est l'arete par laquelle n1 est fils de father */
  815.                 /* on veut tourner autour de a en faisant bouger c vers b */
  816.                 /* i e on tourne dans le sens direct */
  817.         while (     father->voisin[c]->meurtrier
  818.                 ||    conflit ( father->voisin[c],p)         ){
  819.             father->voisin[c]->meurtrier = p;
  820.             a1 = a; b1 = b; c1 = c;
  821.             for (j=U; j<=W; j++)
  822.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  823.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  824.                 else                                                    b=j;
  825.             father = father->voisin[c1] ;
  826.         }
  827.         if (father->fils[c])
  828.                 n1->creation[arete] = n1->voisin[arete] = father->fils[c] ;
  829.         else {  n1->creation[arete] = n1->voisin[arete] = creenoeud(father,c,p);
  830.                 /* le nouveau remplace pere comme voisin de son beau-pere*/
  831.                 for (j=U; j<=W; j++)
  832.                     if (    (father->voisin[c]->s[j] != father->fils[c]->s[V])
  833.                         &&    (father->voisin[c]->s[j] != father->fils[c]->s[W]))
  834.                                                                         break;
  835.                 father->voisin[c]->voisin[j] = father->fils[c] ;
  836.         }
  837.         arete =  (father->fils[c]->direct) ? V : W ;
  838.         father->fils[c]->creation[V+W-arete] =
  839.                         father->fils[c]->voisin[V+W-arete] = n1 ;
  840.         n1 = father->fils[c] ;
  841.         j = a ;
  842.         a = b ;
  843.         b = c ;
  844.         c = j ;
  845.     } while ( father->s[a] != first );
  846.     return 1;
  847. }
  848.  
  849. DT_item delaunay_tree::localise( noeud detecte, DT_item p)
  850. /* determination du plus proche voisin */
  851. {
  852.     DT_item first= NULL,trouve = NULL;
  853.     coord dist, distance = 10000000.0;
  854.     noeud father;
  855.     int a,b,c;        /* indice des trois sommets sur father */
  856.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  857.     int j;
  858.  
  859.     if (!detecte)
  860.                     return NULL;
  861.  
  862.         for (j=U; j<= W - detecte->type; j++) if (confondu(p,detecte->s[j]))
  863.                                     return detecte->s[j];
  864.         detecte->visite = flag++ ;
  865.         a = U; b = V; c = W;
  866.         while (     ( detecte->voisin[c]->visite == flag )
  867.                 ||    conflit ( detecte->voisin[c],p)         ){
  868.             detecte->voisin[c]->visite = flag;
  869.             a1 = a; b1 = b; c1 = c;
  870.             for (j=U; j<=W; j++)
  871.                 if (detecte->voisin[c1]->s[j] == detecte->s[a1])        a=j ;
  872.                 else if (detecte->voisin[c1]->s[j] == detecte->s[b1])    c=j ;
  873.                 else                                                    b=j;
  874.             detecte = detecte->voisin[c1] ;
  875.         }
  876.                 switch (c) {
  877.                     case U : first = detecte->s[a=(detecte->direct) ? W : V ];
  878.                                     break;
  879.                     case V : first = detecte->s[a=(detecte->direct) ? U : W ];
  880.                                     break;
  881.                     case W : first = detecte->s[a=(detecte->direct) ? V : U ];
  882.                                     break;
  883.                 }
  884.                 b = c; c = U+V+W -b -a ;
  885.                 father = detecte;
  886.     do {
  887.                 /* on veut tourner autour de a en faisant bouger c vers b */
  888.                 /* i e on tourne dans le sens direct */
  889.         while (     ( father->voisin[c]->visite == flag )
  890.                 ||    conflit ( father->voisin[c],p)         ){
  891.             father->voisin[c]->visite = flag;
  892.             a1 = a; b1 = b; c1 = c;
  893.             for (j=U; j<=W; j++)
  894.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  895.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  896.                 else                                                    b=j;
  897.             father = father->voisin[c1] ;
  898.         }
  899.         if (father->s[a]->n) {
  900.             dist = (p->x - father->s[a]->x) * (p->x - father->s[a]->x) +
  901.                     (p->y - father->s[a]->y) * (p->y - father->s[a]->y)    ;
  902.             if (dist < distance) { distance = dist; trouve = father->s[a]; }
  903.         }
  904.         j = a ;
  905.         a = b ;
  906.         b = c ;
  907.         c = j ;
  908.     } while ( father->s[a] != first );
  909.     return trouve;
  910. }
  911.  
  912. void delaunay_tree::add_x1x2( reinserer r, noeud v, DT_item p)
  913. /* ajoute v a comme triangle detruit de r */
  914. {
  915.     if ( v->direct )
  916.                      if  (p==v->s[V]) r->detruit1 = v;
  917.                      else              r->detruit2 = v;
  918.     else            
  919.                      if  (p==v->s[W]) r->detruit1 = v;
  920.                      else              r->detruit2 = v;
  921. }
  922.  
  923. void delaunay_tree::add_decroche( reinserer r, noeud v)
  924. /* ajoute v a la liste des decroches de r */
  925. {
  926.     listenoeud nov;
  927.  
  928.     nov = alloc_listenoeud();
  929.     nov->next = r->decroches;
  930.     nov->item = v;
  931.     r->decroches = nov;
  932. }
  933.  
  934. void delaunay_tree::destroy( noeud u, DT_item p)
  935. /* recherche recursive pour initialisation de Reinsert */
  936. {
  937.     int i;
  938.     listenoeud l;
  939.     reinserer rr;
  940.  
  941.     if ( ! u ) return;
  942.     if (u->detruire == flag) return;
  943.     for ( i=U ; i<=W; i++ ) if (u->s[i]==p) break;
  944.     if ( i<=W ) {
  945.         u->detruire = flag;
  946.         if (u->meurtrier)
  947.             for ( i=U ; i<=W; i++ ) if (u->fils[i]) destroy(u->fils[i], p);
  948.         for ( l=u->bfils; l; l = l->next )      destroy(l->item   , p);
  949.         if (u->s[U]==p) return;
  950.         rr = locate(Reinsert,u->s[U]);
  951.         add_x1x2(rr,u,p);
  952.     } else {
  953.         rr = locate(Reinsert,u->s[U]);
  954.         add_decroche(rr,u);
  955.         if (u->pere->detruire == flag)    u->pere        = NULL;
  956.         else                            u->bpere    = NULL;
  957.     }
  958. }
  959.  
  960. void delaunay_tree::recherche( DT_item p)
  961. /* init des structures Star et Reinsert */
  962. {
  963.     DT_item first;
  964.     noeud father;
  965.     int arete;        /* indice sur n1 de l'arete axe-createur */ 
  966.     int a,b,c;        /* indice des trois sommets sur father */
  967.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  968.     int j;
  969.  
  970.     clear_Reinsert(Reinsert); 
  971.     clear_Star();
  972.         arete = (  p->cree->direct  ) ? V : W ;
  973.         first = p->cree->s[V + W - arete ];
  974.         father = p->cree->pere;
  975.         for (j=U; j<=W; j++)
  976.             if (father->s[j] == p->cree->s[V + W - arete ])        a=j ;
  977.             else if (father->s[j] == p->cree->s[arete])            c=j ;
  978.             else                                b=j;
  979.     do {
  980.                 /* ac est l'arete par laquelle on est fils de father */
  981.                 /* on veut tourner autour de a en faisant bouger c vers b */
  982.                 /* et que on tourne autour de a dans le sens inverse */
  983.         while ( ( father->voisin[c]->meurtrier == p )
  984.                 || (father->voisin[c]->visite == flag) ) {
  985.             a1 = a; b1 = b; c1 = c;
  986.             for (j=U; j<=W; j++)
  987.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  988.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  989.                 else                                                    b=j;
  990.             father = father->voisin[c1] ;
  991.             father->visite = flag ;
  992.             father->meurtrier = NULL;
  993.         }
  994.         father->visite = flag ;
  995.         father->meurtrier = NULL;
  996.         a1 = a; b1 = b; c1 = c;
  997.         for (j=U; j<=W; j++)
  998.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  999.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  1000.                 else                                                    b=j;
  1001.         father->voisin[c1]->special[b] = father;
  1002.         if ( father->voisin[c1]->voisin[b]->s[U] == p )
  1003.                                 father->voisin[c1]->voisin[b] = father;
  1004.         plusbeaufils(father->fils[c1], father->voisin[c1] );
  1005.         destroy(father->fils[c1],p);
  1006.         poubelle_noeud(father->fils[c1]);
  1007.         father->fils[c1] = NULL;
  1008.         init_Star(father,a1,b1,c1);
  1009.         a = b1 ;
  1010.         b = c1 ;
  1011.         c = a1 ;
  1012.     } while ( father->s[a] != first );
  1013.     init_Star( (noeud) NULL, 0, 0, 0);
  1014. }
  1015.  
  1016. void delaunay_tree::reinsertion( reinserer n, DT_item p)
  1017. {
  1018.     listenoeud l;
  1019.     noeud u,v,w,ww,w1,w2;
  1020.     DT_item x1,x2;
  1021.     int i,j,k,a,b,c,a1,b1,c1;
  1022.     star s1,s2;
  1023.  
  1024.     /* traitement des noeuds decroches */
  1025.     for ( l=n->decroches; l; l = l->next )
  1026.         if ( l->item->pere ) {
  1027.         /* il faut trouver un nouveau beau-pere et tous les voisinages 
  1028.                    par cette arete */
  1029.             u = l->item->pere;
  1030.             for( i=U; i<=W; i++) if (u->fils[i] == l->item) break;
  1031.             l->item->bpere = u->special[i];
  1032.             l->item->creation[U] = u->special[i];
  1033.             l->item->special[U] = u->special[i];
  1034.             if ( l->item->voisin[U]->detruire == flag )
  1035.                                 l->item->voisin[U] = u->special[i];
  1036.             beaufils(l->item, u->special[i]);
  1037.             for( j=U; j<=W; j++)
  1038.                 if (    (l->item->bpere->s[j] != l->item->s[V] )
  1039.                     &&    (l->item->bpere->s[j] != l->item->s[W] ) ) break;
  1040.             l->item->bpere->voisin[j] = l->item;
  1041.         } else {
  1042.         /* il faut trouver un nouveau pere */
  1043.             u = l->item->bpere;
  1044.             for( i=U; i<=W; i++) if (u->s[i] == l->item->s[V]) break;
  1045.             for( j=U; j<=W; j++) if (u->s[j] == l->item->s[W]) break;
  1046.             i = U+V+W -i -j;
  1047.             u= l->item->pere = u->special[i];
  1048.             for( i=U; i<=W; i++) if (u->s[i] == l->item->s[V]) break;
  1049.             for( j=U; j<=W; j++) if (u->s[j] == l->item->s[W]) break;
  1050.             i = U+V+W -i -j;
  1051.             u->fils[i] = l->item;
  1052.         }
  1053.     /* traitement des noeuds detruits */
  1054.     if ( ! n->detruit1 ) return;
  1055.     x1 =  ( n->detruit1->s[V] == p ) ? n->detruit1->s[W] : n->detruit1->s[V];
  1056.     x2 =  ( n->detruit2->s[V] == p ) ? n->detruit2->s[W] : n->detruit2->s[V];
  1057.     s1 = loc_Star(x1);
  1058.     s2 = loc_Star(x2)->previous ;
  1059.     u = s1->triangle;
  1060.     /* Cas 1 (triangle x x1 x2 a creer) u n'est pas en conflit avec x */
  1061.     if ( ! conflit(u, n->x) ) {
  1062.             /* u est le beau pere de x x1 x2 a cree */
  1063.             for( i=U; i<=W; i++) if (u->s[i] == x1) break;
  1064.             for( j=U; j<=W; j++) if (u->s[j] == x2) break;
  1065.             k = U+V+W -i -j;
  1066.             u = u->voisin[k] ;
  1067.             /* u est le pere */
  1068.             for( i=U; i<=W; i++) if (u->s[i] == x1) break;
  1069.             for( j=U; j<=W; j++) if (u->s[j] == x2) break;
  1070.             i = U+V+W -i -j;
  1071.             n->x->cree =ww = creenoeud(u ,i,n->x);
  1072.         /* ww est le fils de son pere */
  1073.             u->voisin[i] = ww->bpere;        /* voisin a la mort */
  1074.         /* voisinage beau-fils beau-pere */
  1075.             ww->bpere->voisin[k] = ww;
  1076.         /* voisinage avec les "freres" du nouveau */
  1077.             i = ( ww->s[V] == x1 ) ? V : W ;
  1078.             u = n->detruit2->creation[(n->detruit2->s[V]==p)?V:W] ;
  1079.             ww->voisin[i] = ww->creation[i] = u;
  1080.             for( j=U; j<=W; j++) if ( u->creation[j] == n->detruit2 ) break;
  1081.             u->creation[j] = u->special[j] = ww ;
  1082.             if ( u->voisin[j]->detruire == flag ) u->voisin[j] = ww ;
  1083.             if ( u->voisin[j]->visite == flag ) u->voisin[j] = ww ;
  1084.             u = n->detruit1->creation[(n->detruit1->s[V]==p)?V:W] ;
  1085.             ww->voisin[V+W-i] = ww->creation[V+W-i] = u;
  1086.             for( j=U; j<=W; j++) if ( u->creation[j] == n->detruit1 ) break;
  1087.             u->creation[j] = u->special[j] = ww ;
  1088.             if ( u->voisin[j]->detruire == flag ) u->voisin[j] = ww ;
  1089.             if ( u->voisin[j]->visite == flag ) u->voisin[j] = ww ;
  1090.         /* mise a jour de Star */
  1091.             poubelle_noeud(n->detruit1);
  1092.             poubelle_noeud(n->detruit2);
  1093.             split_Star(s1,s2); s2=s1->next;
  1094.             s1->triangle = ww;
  1095.             s2->triangle = ww;
  1096.             for( i=U; i<=W; i++) if (ww->s[i] == x1)    s1->p = s2->arete = i;
  1097.                         else     if (ww->s[i] == n->x ) s1->n = s2->p = i;
  1098.                         else                           s1->arete = s2->n = i;
  1099.             ww->Star[s1->arete] = s1;
  1100.             ww->Star[s2->arete] = s2;
  1101.     return;
  1102.     }
  1103.     /* Cas 2  */
  1104.     v = u; w1=NULL;
  1105.     w = n->detruit1->creation[(n->detruit1->s[V]==p)?V:W] ;
  1106.     a = s1->p ;
  1107.     c = s1->n ;
  1108.     b = s1->arete ;
  1109.     do {
  1110.     /* on tourne dans le sens inverse */
  1111.         while ( conflit( v->voisin[c], n->x ) ) {
  1112.             a1 = a; b1 = b; c1 = c;
  1113.             for (j=U; j<=W; j++) if ( v->voisin[c1]->s[j] == v->s[a1]) a = j;
  1114.                         else     if ( v->voisin[c1]->s[j] == v->s[b1]) c = j;
  1115.                         else                                           b = j;
  1116.             v = v->voisin[c1];
  1117.             v->meurtrier = n->x;
  1118.         }
  1119.             v->meurtrier = n->x;
  1120.             ww = creenoeud(v,c,n->x);
  1121.         /* voisinage beau-fils beau-pere */
  1122.             for (j=U; j<=W; j++)
  1123.                     if (    ( ww->bpere->s[j] != ww->s[V] )
  1124.                         &&    ( ww->bpere->s[j] != ww->s[W] ) ) break;
  1125.             if ( ww->bpere->visite == flag ){ /* le beau-pere est dans A */
  1126.                 ww->bpere->voisin[j] = ww;
  1127.             } else {
  1128.                 ww->bpere->special[j] = ww;
  1129.                 if ( ww->bpere->voisin[j]->detruire == flag )
  1130.                                                 ww->bpere->voisin[j] = ww ;
  1131.                 if ( ww->bpere->voisin[j]->visite == flag )
  1132.                                                 ww->bpere->voisin[j] = ww ;
  1133.             }
  1134.         /* voisinage nouvelle arete */
  1135.             for (j=U;j<=W;j++) if((ww->s[j]!=n->x)&&(ww->s[j]!=v->s[a]))break;
  1136.             ww->voisin[j] = ww->creation[j] = w ;
  1137.             if ( !w1 ) {
  1138.               for (j=U;j<=W;j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1139.               w1 = w->special[j] = w->creation[j] = ww ;
  1140.               if (w->voisin[j]->visite == flag ) w->voisin[j] = ww ;
  1141.               if (w->voisin[j]->detruire == flag ) w->voisin[j] = ww ;
  1142.             } else {
  1143.               for (j=U;j<=W;j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1144.               w->voisin[j] = w->creation[j] = ww ;
  1145.             }
  1146.             w = ww;
  1147.         /* mise a jour de Star */
  1148.             if ( ww->bpere->visite != flag ){/* le beau-pere n'est pas dans A */
  1149.                 v->Star[c]->triangle = ww;
  1150.                 ww->Star[U] = v->Star[c];
  1151.                 ww->Star[U]->arete = U;
  1152.                 ww->Star[U]->n = (v->s[a] == w->s[V] ) ? V : W ;
  1153.                 ww->Star[U]->p = V+W-ww->Star[U]->n ;
  1154.             }
  1155.         j = a ; a = b ; b = c ; c = j ;
  1156.     } while ( v->s[a] != x2) ; 
  1157.         /* voisinage autour de x x2 */
  1158.             n->x->cree = w2 = w;
  1159.             ww = n->detruit2->creation[(n->detruit2->s[V]==p)?V:W] ;
  1160.             for (j=U; j<=W; j++) if((ww->s[j]!=n->x)&&(ww->s[j]!=v->s[a]))break;
  1161.             if (ww->voisin[j]->visite == flag ) ww->voisin[j] = w ;
  1162.             if (ww->voisin[j]->detruire == flag ) ww->voisin[j] = w ;
  1163.             ww->creation[j] = ww->special[j] = w ;
  1164.             for (j=U; j<=W; j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1165.             w->voisin[j] = w->creation[j] = ww ;
  1166.     do {
  1167.     /* on tourne toujours dans le sens inverse */
  1168.         while ( conflit( v->voisin[c], n->x ) ) {
  1169.             a1 = a; b1 = b; c1 = c;
  1170.             for (j=U; j<=W; j++) if ( v->voisin[c1]->s[j] == v->s[a1]) a = j;
  1171.                         else     if ( v->voisin[c1]->s[j] == v->s[b1]) c = j;
  1172.                         else                                           b = j;
  1173.             v = v->voisin[c1];
  1174.             v->meurtrier = n->x;
  1175.         }
  1176.             v->meurtrier = n->x;
  1177.         j = a ; a = b ; b = c ; c = j ;
  1178.     } while ( v->s[a] != x1) ; 
  1179.         /* mise a jour de Star */
  1180.             split_Star(s1,s2); s2=s1->next;
  1181.             s1->triangle = w1;
  1182.             s2->triangle = w2;
  1183.             poubelle_noeud(n->detruit1);
  1184.             poubelle_noeud(n->detruit2);
  1185.             for( i=U; i<=W; i++) if (w1->s[i] == x1)    s1->p = i;
  1186.                         else     if (w1->s[i] == n->x ) s1->n = i;
  1187.                         else                            s1->arete = i;
  1188.             w1->Star[s1->arete] = s1;
  1189.             for( i=U; i<=W; i++) if (w2->s[i] == x2)    s2->n = i;
  1190.                         else     if (w2->s[i] == n->x ) s2->p = i;
  1191.                         else                            s2->arete = i;
  1192.             w2->Star[s2->arete] = s2;
  1193. }
  1194.  
  1195. void delaunay_tree::parcours( reinserer n, DT_item p)
  1196. {
  1197.     if ( ! n ) return;
  1198.     parcours(n->finf,p);
  1199.     reinsertion(n,p);
  1200.     parcours(n->fsup,p);
  1201. }
  1202.  
  1203.  
  1204. void delaunay_tree::trace_items(noeud n, delaunay_f2* trace_item)
  1205. /* exploration recursive pour le trace des points */
  1206. {
  1207.   noeud* stack = new noeud[counter+10];
  1208.   int top = 0;
  1209.   stack[0] = n;
  1210.   n->stacked = flag;
  1211.  
  1212.   while (top >= 0)
  1213.   { n = stack[top--];   //pop
  1214.     n->visite = flag;
  1215.     for (int i=U; i<=W; i++)
  1216.       if ( n->s[i] && n->s[i]->visite != flag )
  1217.             { n->s[i]->visite = flag ;
  1218.               trace_item(n->s[i]->x, n->s[i]->y);
  1219.              }
  1220.  
  1221.     for (i=W; i>=U; i--)
  1222.         { noeud v = n->voisin[i];
  1223.       if ( v->stacked != flag )
  1224.            { stack[++top] = v;          //push
  1225.              v->stacked = flag;
  1226.             }
  1227.          }
  1228.  
  1229.    } // while stack not empty
  1230.  
  1231.  delete stack;
  1232.  
  1233. }
  1234.  
  1235. void delaunay_tree::list_items(noeud n, list<DT_item>& L)
  1236. /* exploration recursive pour le trace des points */
  1237. {
  1238.   noeud* stack = new noeud[counter+10];
  1239.   int top = 0;
  1240.   stack[0] = n;
  1241.   n->stacked = flag;
  1242.  
  1243.   while (top >= 0)
  1244.   { n = stack[top--];   //pop
  1245.     n->visite = flag;
  1246.     for (int i=U; i<=W; i++)
  1247.       if ( n->s[i] && n->s[i]->visite != flag )
  1248.             { n->s[i]->visite = flag ;
  1249.               L.append(n->s[i]);
  1250.              }
  1251.  
  1252.     for (i=W; i>=U; i--)
  1253.         { noeud v = n->voisin[i];
  1254.       if ( v->stacked != flag )
  1255.            { stack[++top] = v;          //push
  1256.              v->stacked = flag;
  1257.             }
  1258.          }
  1259.  
  1260.    } // while stack not empty
  1261.  
  1262.  delete stack;
  1263.  
  1264. }
  1265.  
  1266. void delaunay_tree::clear_items(noeud n)
  1267. {
  1268.   noeud* stack = new noeud[counter+10];
  1269.   int top = 0;
  1270.   stack[0] = n;
  1271.   n->stacked = flag;
  1272.  
  1273.   while (top >= 0)
  1274.   { n = stack[top--];   //pop
  1275.     n->visite = flag;
  1276.     for (int i=U; i<=W; i++)
  1277.       if ( n->s[i] && n->s[i]->visite != flag )
  1278.             { n->s[i]->visite = flag ;
  1279.               clear_inf(n->s[i]->i);
  1280.              }
  1281.  
  1282.     for (i=W; i>=U; i--)
  1283.         { noeud v = n->voisin[i];
  1284.       if ( v->stacked != flag )
  1285.            { stack[++top] = v;          //push
  1286.              v->stacked = flag;
  1287.             }
  1288.          }
  1289.  
  1290.    } // while stack not empty
  1291.  
  1292.  delete stack;
  1293. }
  1294.  
  1295.  
  1296. void delaunay_tree::del_noeud( noeud n, delaunay_f4* trace_segment,int both)
  1297. /* exploration recursive de delaunay_tree */
  1298. {
  1299.   noeud* stack = new noeud[counter+10];
  1300.   int top = 0;
  1301.   stack[0] = n;
  1302.   n->stacked = flag;
  1303.  
  1304.   int i;
  1305.  
  1306.   while (top >= 0)
  1307.   { n = stack[top--];   //pop
  1308.  
  1309.     n->visite = flag;
  1310.  
  1311.     for (i=U; i<=W; i++)
  1312.           if ( both || n->voisin[i]->visite != flag ) 
  1313.            { int j = (i==U) ? V : U ; 
  1314.              int k = U + V + W -i -j ;
  1315.          if (( n->type == Fini ) || ((i == W) && (n->type==Infini1) ) )
  1316.                 trace_segment(n->s[j]->x,n->s[j]->y, n->s[k]->x, n->s[k]->y);
  1317.         }
  1318.  
  1319.     for (i=W; i>=U; i--)
  1320.         { noeud v = n->voisin[i];
  1321.       if ( v->stacked != flag )
  1322.            { stack[++top] = v;          //push
  1323.              v->stacked = flag;
  1324.             }
  1325.          }
  1326.  
  1327.    } // while stack not empty
  1328.  
  1329.  delete stack;
  1330.  
  1331.  }
  1332.  
  1333.  
  1334. void delaunay_tree::vor( noeud n, delaunay_f6* trace_segment, delaunay_F6* pt_infi, int both)
  1335. {
  1336.  
  1337.   int i,j;
  1338.   coord x,y,mx,my;
  1339.   int order[3];
  1340.  
  1341.   int top = 0;
  1342.   noeud* stack = new noeud[counter+10];
  1343.   stack[0] = n;
  1344.   n->stacked = flag;
  1345.  
  1346.   while (top >= 0)
  1347.   { 
  1348.     n = stack[top--];   //pop
  1349.  
  1350.     n->visite = flag;
  1351.  
  1352.         if (n->direct)
  1353.          { order[0] = 0;
  1354.            order[1] = 1;
  1355.            order[2] = 2;
  1356.           }
  1357.         else 
  1358.          { order[0] = 2;
  1359.            order[1] = 1;
  1360.            order[2] = 0;
  1361.           }
  1362.  
  1363.     for (j=0; j<3; j++)
  1364.         { 
  1365.           int i = order[j];
  1366.  
  1367.                if (both ||  n->voisin[i]->visite != flag )
  1368.         {   int k;
  1369.                     if (n->direct)
  1370.                        k = (i==2) ? 0 : i+1; 
  1371.                     else 
  1372.                        k = (i==0) ? 2 : i-1; 
  1373.  
  1374.             coord sx0 = n->s[k]->x;
  1375.                     coord sy0 = n->s[k]->y;
  1376.  
  1377.             switch (n->type){
  1378.             case Fini :
  1379.             if (! n->degenere ) {
  1380.                 switch ( n->voisin[i]->type ){
  1381.                 case Fini : if ( ! n->voisin[i]->degenere ){
  1382. trace_segment(n->cx,n->cy, n->voisin[i]->cx, n->voisin[i]->cy,sx0,sy0); 
  1383.                                             break;
  1384.                 }
  1385.                 case Infini1  : 
  1386.                   pt_infi(n->cx,n->cy, n->voisin[i]->cx, n->voisin[i]->cy,&x,&y);
  1387.                                   trace_segment(n->cx, n->cy,x,y,sx0,sy0);
  1388.                   break ;
  1389.                 }
  1390.                 break;
  1391.             }
  1392.             case Infini1  :
  1393.                 if ( n->degenere &&  n->voisin[i]->degenere ) break;
  1394.                 switch ( n->voisin[i]->type ){
  1395.                 case Fini :
  1396.                 if ( ! n->voisin[i]->degenere ) 
  1397.                                 { pt_infi(n->voisin[i]->cx, 
  1398.                                           n->voisin[i]->cy, 
  1399.                                           n->cx,n->cy,&x,&y);
  1400.                                   trace_segment(x,y,
  1401.                                                 n->voisin[i]->cx, 
  1402.                                                 n->voisin[i]->cy,
  1403.                                                 sx0,sy0);
  1404.                   break ;
  1405.                  }
  1406.                 case Infini1  :
  1407.                   if (i == W)
  1408.                                   { mx = ( n->s[U]->x + n->s[V]->x )/2 ;
  1409.                     my = ( n->s[U]->y + n->s[V]->y )/2 ;
  1410.                     pt_infi(mx,my, n->cx,n->cy,&x,&y);
  1411.                     pt_infi(mx,my, n->voisin[i]->cx, 
  1412.                                                    n->voisin[i]->cy,&mx, &my);
  1413.                     trace_segment(mx,my, x,y,sx0,sy0);
  1414.                    }
  1415.                 }
  1416.                 break;
  1417.  
  1418.             } //switch
  1419.  
  1420.                   } //if
  1421.  
  1422.            }  // for
  1423.  
  1424.     for (i=W; i>=U; i--)
  1425.         { noeud v = n->voisin[i];
  1426.       if ( v->stacked != flag )
  1427.            { stack[++top] = v;          //push
  1428.              v->stacked = flag;
  1429.             }
  1430.          }
  1431.  
  1432.    } // while stack not empty
  1433.  
  1434.  delete stack;
  1435.  
  1436. }
  1437.  
  1438. DT_item delaunay_tree::neighbor(double x,double y)
  1439. /* recherche du plus proche voisin de (x,y) */
  1440. {
  1441.     DT_POINT requete;
  1442.     DT_item reponse;
  1443.  
  1444.     flag++;
  1445.     if (arbre == nouveau) return NULL;
  1446.     requete.x = x; requete.y = y;
  1447.     reponse = localise(Insert(arbre,&requete), &requete);
  1448.     return  reponse;
  1449. }
  1450.  
  1451. void delaunay_tree::del(double x, double y)
  1452. { DT_item p = neighbor(x,y);
  1453.   if (p==nil || p->x != x || p->y != y) return;
  1454.   del_item(p);
  1455.  }
  1456.  
  1457. void delaunay_tree::del_item( DT_item ppp)
  1458. {
  1459.     DT_item p;
  1460.  
  1461.     if (!ppp) return;
  1462.  
  1463.     flag++;
  1464.     p = (DT_item) ppp ;
  1465.     nouveau = p->cree->pere;    /* pour si on supprime le dernier */
  1466.     recherche(p);
  1467.     last = nouveau ;
  1468.     parcours(Reinsert,p);
  1469.         clear_inf(p->i);
  1470.         counter--;
  1471.     poubelle_point(p);
  1472. }
  1473.  
  1474. DT_item delaunay_tree::insert( coord x, coord y, void* inf)
  1475. /* procedure d'insertion d'un point dans l'arbre */
  1476. {
  1477.     DT_item p;
  1478.  
  1479.     flag++;
  1480.     p = alloc_point();
  1481.     p->x = x;
  1482.     p->y = y;
  1483.         p->i = inf;
  1484.     p->n = flag;
  1485.     if (! creation( Insert(arbre,p), p )) 
  1486.         { poubelle_point(p); 
  1487.           return neighbor(x,y);
  1488.          }
  1489.         copy_inf(inf);
  1490.         counter++;
  1491.     last = nouveau ;
  1492.     return p;
  1493. }
  1494.  
  1495. void delaunay_tree::all_items(list<DT_item>& L)
  1496. /* procedure tracant tous les points */
  1497. {
  1498.     if (arbre == nouveau) return;
  1499.     flag++;
  1500.     arbre->s[U]->visite = flag;
  1501.     arbre->s[V]->visite = flag;
  1502.     arbre->s[W]->visite = flag;
  1503.     list_items(nouveau, L);
  1504. }
  1505.  
  1506. void delaunay_tree::trace_triang_edges( delaunay_f4 *seg,int both)
  1507. /* procedure de trace de delaunay */
  1508. {
  1509.     if (arbre == nouveau) return;
  1510.     flag++;
  1511.     del_noeud(nouveau,seg, both);
  1512. }
  1513.  
  1514. void delaunay_tree::trace_voronoi_sites(delaunay_f2 *trace_item)
  1515. {
  1516.     if (arbre == nouveau) return;
  1517.     flag++;
  1518.     trace_items(nouveau,trace_item);
  1519. }
  1520.  
  1521. void delaunay_tree::trace_voronoi_edges(delaunay_f6 *trace_seg, delaunay_F6 *pt_infi, int both)
  1522. {
  1523.     if (arbre == nouveau) return;
  1524.     flag++;
  1525.     vor(nouveau,trace_seg,pt_infi, both);
  1526. }
  1527.  
  1528. void delaunay_tree::convex_hull(list<DT_item>& CH)
  1529.  CH.clear();
  1530.  
  1531.  if (arbre == nouveau) return;
  1532.  
  1533.  for (int j=2;j>=0;j--)
  1534.  { noeud v = arbre->voisin[0];
  1535.  
  1536.    int i = (j == 0) ? 2 : j-1;
  1537.  
  1538.    DT_item start = v->s[i];
  1539.  
  1540.    do
  1541.    { int k;
  1542.      if (v->type == Infini1) CH.append(v->s[i]);
  1543.      if (v->direct)
  1544.         k = (i == 0) ? 2 : i-1;
  1545.      else
  1546.         k = (i == 2) ? 0 : i+1;
  1547.      noeud w = v->voisin[k];
  1548.      for(i=0;w->voisin[i] != v;i++); 
  1549.      v = w;
  1550.     } while (v->s[i] != start);
  1551.  
  1552.   }
  1553. }
  1554.  
  1555.